// 组合模式

// 文件夹和文件

// Folder
const Folder = function (name) {
    this.name = name;
    this.parent = null;
    this.files = [];
}

Folder.prototype.add = function (file) {
    file.parent = this;
    this.files.push(file);
}

Folder.prototype.scan = function (file) {
    console.log('scan folder');
    for (let i = 0; i < this.files.length; i++) {
        this.files[i].scan();
    }
}

Folder.prototype.remove = function(file) {
    if (!this.parent) {
        return;
    }
    for (let i = 0; i < this.parent.files.length; i++) {
        if (this.parent.files[i] = file) {
            this.parent.files.splice(i, 1)
        }
    }
}

// File
const File = function (name) {
    this.name = name;
    this.parent = null;
}

File.prototype.add = function () {
    throw new Error('不能再加了');
}

File.prototype.scan = function () {
    console.log(`扫描了${this.name}`);
}

File.prototype.remove = function() {
    if (!this.parent) {
        return;
    }
    for (let i = 0; i < this.parent.files.length; i++) {
        if (this.parent.files[i] = file) {
            this.parent.files.splice(i, 1)
        }
    }
}

const folder = new Folder('学习资料');
const folder1 = new Folder('javascript');
const folder2 = new Folder('html');

const file1 = new File('js基础');
const file2 = new File('js进阶');
const file3 = new File('html5');

folder1.add(file1);
folder1.add(file2);
folder2.add(file3);

// 硬盘里要复制进来的
const folder3 = new Folder('node');
const file4 = new File('node.js')

folder3.add(file4);
const file5 = new File('js高级');

// 添加操作
folder.add(folder3);
folder.add(file5);

folder.scan();

// 组合模式 -> HAS-A 聚合关系 不是 IS-A 父子关系


// 模版方法模式
//mix-in

// Coffee or Tea
const Coffee = function() {}
Coffee.prototype.boilWater = function () {
    console.log('把水煮沸');
}
Coffee.prototype.brewCoffeeGriends = function () {
    console.log('泡咖啡');
}
Coffee.prototype.pourInCup = function () {
    console.log('把咖啡倒进杯子');
}
Coffee.prototype.addSugarAndMilk = function () {
    console.log('加糖和牛奶');
}

Coffee.prototype.init = function () {
    this.boilWater();
    this.brewCoffeeGriends();
    this.pourInCup();
    this.addSugarAndMilk();
}

const coffee = new Coffee();
coffee.init();

const Tea = function() {}
Tea.prototype.boilWater = function () {
    console.log('把水煮沸');
}
Tea.prototype.steapTeaBag = function () {
    console.log('用沸水浸泡茶叶');
}
Tea.prototype.pourInCup = function () {
    console.log('把茶倒进杯子');
}
Tea.prototype.addLemon = function () {
    console.log('加柠檬');
}

Tea.prototype.init = function () {
    this.boilWater();
    this.steapTeaBag();
    this.pourInCup();
    this.addLemon();
}

const tea = new Tea();
tea.init();

// 重写Coffee or Tea
const Drinking = function () {}
Drinking.prototype.boilWater = function () {
    console.log('把水煮沸');
}
Drinking.prototype.brew = function () {
    throw new Error('子类必须实现这个方法');
}
Drinking.prototype.pourInCup = function() {}
Drinking.prototype.addCondiments = function () {}

Drinking.prototype.customerWantsCondiments = function () {
    return true;
}

Drinking.prototype.init = function () {
    this.boilWater();
    this.brew();
    this.pourInCup();
    if (this.customerWantsCondiments()) {
        this.addCondiments();
    }
}

const Coffee = function() {}
Coffee.prototype = new Drinking();
Coffee.prototype.brew = function () {
    console.log('用沸水冲泡咖啡');
}
Coffee.prototype.pourInCup = function () {
    console.log('把咖啡倒进杯子');
}
Coffee.prototype.addCondiments = function () {
    console.log('加糖和牛奶');
}
const coffee = new Coffee();
coffee.init();

const CoffeeWithHook = function() {}
CoffeeWithHook.prototype = new Drinking();
CoffeeWithHook.prototype.brew = function () {
    console.log('用沸水冲泡咖啡');
}
CoffeeWithHook.prototype.pourInCup = function () {
    console.log('把咖啡倒进杯子');
}
CoffeeWithHook.prototype.addCondiments = function () {
    console.log('加糖和牛奶');
}
CoffeeWithHook.prototype.customerWantsCondiments = function () {
    return window.confirm('是否需要加调料');
}
const coffeeWithHook = new CoffeeWithHook();
coffeeWithHook.init();

const Tea = function() {}
Tea.prototype = new Drinking();
Tea.prototype.brew = function () {
    console.log('用沸水冲泡茶');
}
Tea.prototype.pourInCup = function () {
    console.log('把茶倒进杯子');
}
Tea.prototype.addCondiments = function () {
    console.log('加柠檬');
}
const tea = new Tea();
tea.init();



// new 好莱坞原则

const DrinkingHollywood = function (params) {
    const boilWater = function() {
        console.log('把水煮沸');
    }
    const brew = params.brew || function () {
        throw new Error('必须传递brew');
    }
    const pourInCup = params.pourInCup || function () {
        throw new Error('必须传递pourInCup');
    }
    const addCondiments = params.addCondiments || function () {
        throw new Error('必须传递addCondiments');
    }
    const F = function() {}
    F.prototype.init = function () {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    return F
}

const CoffeeHollywood = DrinkingHollywood({
    brew: function() {
        console.log('用沸水冲泡咖啡');
    },
    pourInCup: function () {
        console.log('把咖啡装进杯子里');
    },
    addCondiments: function() {
        console.log('加糖和牛奶');
    }
});

const TeaHollywood = DrinkingHollywood({
    brew: function() {
        console.log('用沸水浸泡茶');
    },
    pourInCup: function () {
        console.log('把茶装进杯子里');
    },
    addCondiments: function() {
        console.log('加柠檬');
    }
});

const coffeeHollywood = new CoffeeHollywood();
coffeeHollywood.init();
const teaHollywood = new TeaHollywood();
teaHollywood.init();